/**
 * 并发请求
 * @param {string[]} urls 带请求的url数组
 * @param {number} maxNum 一次最大请求并发数
 * @param {Function} asyncFun 异步请求的方法
 */
function curconRequest(urls, maxNum, asyncFun) {
  return new Promise((resolve, reject) => {
    // 指向当前发送请求地址的下标
    let index = 0;
    // 完成请求的数量
    let count = 0;
    const results = [];
    async function _runTask() {
      const i = index;
      const url = urls[index];
      index++;
      try {
        const resp = await asyncFun(url);
        results[i] = resp;
      } catch (err) {
        results[i] = err;
      } finally {
        count++;
        if (count === urls.length) {
          resolve[results];
        }
        if (index < urls.length) {
          _runTask();
        }
      }
      // fetch(url).then(res => {
      //     results[i] = res
      // }).catch(err => {
      //     results[i] = err
      // }).finally(() => {
      //     count++
      //     if(count === urls.length) {
      //         resolve[results]
      //     }
      //     if (index < urls.length) {
      //         runTask()
      //     }
      // })
    }
    // 如果传入的数组长度比最大并发数小，取数组长度
    for (let i = 0; i < Math.min(urls.length, maxNum); i++) {
      _runTask();
    }
  });
}



// 并发任务
class TaskQueue {
    constructor(maxNum, callback) {
        this.maxNum = maxNum
        this.running = 0
        this.index = 0
        this.quene = []
        this.results = []
        this.callback = callback
    }

    addTask(task) {
        this.quene.push({
            index: this.index,
            task
        })
        this.index++
        this.next()
    }

    next() {
        while(this.running < this.maxNum && this.quene.length) {
            const {index, task} = this.quene.shift()
            task().then(res => {
                this.results[index] = res
            }).catch((err) => {
                this.results[index] = err
            }).finally(() => {
                this.running--
                this.next()
            })
            this.running++
        }
        // 等所有异步任务执行完成之后返回数据
        if (typeof this.callback === 'function' && this.running === 0) {
            this.callback(this.results)
        }
    }
}

function startLimit() {
    const quene = new TaskQueue(2, (results) => {
        console.log(results)
    })
    
    function timeouter(timer) {
        return new Promise((resolve) => {
            setTimeout(() => {
                resolve(timer)
            }, timer)
        })
    }
    
    quene.addTask(() => timeouter(10000))
    quene.addTask(() => timeouter(3000))
    quene.addTask(() => timeouter(2000))
    quene.addTask(() => timeouter(8000))
}